package com.tbit.uqbike.webmanager.controller;

import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.common.enums.OperaPswEnum;
import com.tbit.uqbike.annos.OperateLog;
import com.tbit.uqbike.constant.SubAccountConstant;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.SubAccount;
import com.tbit.uqbike.object.pojo.SubAccountBind;
import com.tbit.uqbike.object.pojo.dto.SubAccountDTO;
import com.tbit.uqbike.object.pojo.dto.SubAccountMerchantsDTO;
import com.tbit.uqbike.object.pojo.dto.SubAccountRatioDTO;
import com.tbit.uqbike.object.pojo.dto.UserMoneyRefundDTO;
import com.tbit.uqbike.object.pojo.vo.*;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.common.entity.view.PageResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.OperaPswService;
import com.tbit.uqbike.service.business.RefundService;
import com.tbit.uqbike.service.business.SubAccountService;
import com.tbit.uqbike.webmanager.util.Assert;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import com.tbit.utils.ValidList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 分账管理
 *
 * @Author:BUGTian
 * @DATE: 2022/5/23
 */
@RestController
@RequestMapping("/subAccount")
public class SubAccountController {

    @Autowired
    private SubAccountService subAccountService;
    @Autowired
    private RefundService refundService;
    @Autowired
    private OperaPswService operaPswService;

    /**
     * 创建分账账户
     *
     * @param subAccountDTO
     * @return
     */
    @PostMapping("/createMember")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_ADD)
    public Result createMember(SubAccountDTO subAccountDTO) {
        return subAccountService.createMember(subAccountDTO);
    }


    /**
     * 分页查询分账账户信息
     *
     * @param accountId 品牌id
     * @param page      当前页码
     * @param size      每页显示的行
     * @param state     状态（0：审核中，1：正常，2：已删除，3：异常）
     * @param nickName  用户昵称
     * @param phone     用户手机号
     * @return
     */
    @GetMapping("/queryPage")
    public Result<PageResult<SubAccount>> queryPage(Integer accountId,
                                                    @RequestParam(defaultValue = "1") Integer page,
                                                    @RequestParam(defaultValue = "100") Integer size,
                                                    Integer state, String nickName,
                                                    String phone) {
        Assert.notNull(accountId,"请选择品牌");
        PageResult<SubAccount> pageResult = subAccountService.queryPage(accountId, page, size, state, nickName, phone);
        return Result.success(pageResult);
    }

    /**
     * 修改分账账户昵称
     *
     * @param subAccountId 分账账户id
     * @param nickName     昵称
     * @return
     */
    @PutMapping("/update")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_EDIT)
    public Result updateMember(Integer subAccountId, String nickName,String autoRemark) {
        subAccountService.updateMember(subAccountId, nickName, autoRemark);
        return Result.success();
    }

    /**
     * 删除分账账户
     *
     * @param subAccountId 分账账户id
     * @return
     */
    @DeleteMapping("/delete")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_DELETE)
    public Result deleteMember(Integer subAccountId) {
        return subAccountService.deleteMember(subAccountId);
    }

    /**
     * 分账账户绑定登录账户
     *
     * @param subAccountBind
     * @return
     */
    @PostMapping("/bandAccountUser")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_BAND)
    public Result bandAccountUser(@RequestBody SubAccountBind subAccountBind) {
        return subAccountService.bandAccountUser(subAccountBind);
    }

    /**
     * 查询绑定用户列表
     *
     * @param page         当前页码
     * @param size         每页显示的行
     * @param subAccountId 分账账户id
     * @return
     */
    @GetMapping("/queryBandAccountUser")
    public Result<PageResult<SubAccountBandUserVO>> queryBandAccountUser(@NotNull Integer subAccountId, @NotNull Integer page, @NotNull Integer size) {
        return subAccountService.queryBandAccountUser(subAccountId, page, size);
    }


    /**
     * 删除绑定关系
     *
     * @param subAccountId  分账账户id
     * @param accountUserId 登录用户id
     * @return
     */
    @DeleteMapping("/deleteBand")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_UNBAND)
    public Result deleteBand(@NotNull Integer subAccountId, @NotNull Integer accountUserId) {
        return subAccountService.deleteBand(subAccountId, accountUserId);
    }

    /**
     * 分账比例设置
     *
     * @param subAccountRatioDTO 分账比例设置对象
     */
    @PostMapping("/addSubAccountRatio")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_RATIO_SET)
    public Result addSubAccountRatio(@Validated @RequestBody SubAccountRatioDTO subAccountRatioDTO, HttpServletRequest request) {
        if (subAccountRatioDTO.getType() == SubAccountConstant.MACHINE_DIVIDE && subAccountRatioDTO.getMachineGroupId() == null) {
            throw new BaseException("选择车辆分账时分组id不能为空");
        }
        LoginInfo loginInfo = BaseController.getLogin(request);
        return subAccountService.addSubAccountRatio(subAccountRatioDTO, loginInfo);
    }

    /**
     * 批量设置车辆分组分账比例
     */
    @PostMapping("/batchAddMachineGroupRatio")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_RATIO_SET)
    public Result<Void> batchAddRatio(@Validated @RequestBody ValidList<SubAccountRatioDTO> dtoList, HttpServletRequest request) {
        if (dtoList.stream().anyMatch(dto -> dto.getType() == SubAccountConstant.AREA_DIVIDE)) {
            throw new BaseException("批量设置分账比例不支持区域分账");
        }
        if (dtoList.stream().anyMatch(dto -> dto.getMachineGroupId() == null)) {
            throw new BaseException("车辆分组id不能为空");
        }
        LoginInfo loginInfo = BaseController.getLogin(request);
        return subAccountService.batchAddMachineGroupRatio(dtoList, loginInfo);
    }


    /**
     * 查询分账比例
     *
     * @param page      当前页码
     * @param size      每页显示的行
     * @param accountId 区域id
     * @param state     状态(0:未生效，1:生效中，2:已过期)
     * @param groupId   分组id
     * @param type      分账类型(1-区域分账 2-车辆分账)
     */
    @GetMapping("/querySubAccountRatio")
    public Result<PageResult<SubAccountRatioVO>> querySubAccountRatio(@NotNull Integer page, @NotNull Integer size,
                                                                      @NotNull Integer accountId, Integer state,
                                                                      String groupId, @RequestParam(defaultValue = "1") Integer type) {
        PageResult<SubAccountRatioVO> pageResult = subAccountService.querySubAccountRatio(page, size, accountId, state, groupId, type);
        return Result.success(pageResult);
    }

    /**
     * 分组查询分账比例
     *
     * @param page      当前页码
     * @param size      每页显示的行
     * @param accountId 区域id
     * @param state     状态(0:未生效，1:生效中，2:已过期)
     * @param type      分账类型(1-区域分账 2-车辆分账)
     */
    @GetMapping("/querySubAccountGroupRatio")
    public Result<PageResult<SubAccountRatioGroupVO>> querySubAccountGroupRatio(@NotNull Integer page, @NotNull Integer size, @NotNull Integer accountId, Integer state, @RequestParam(defaultValue = "1") Integer type) {
        PageResult<SubAccountRatioGroupVO> pageResult = subAccountService.querySubAccountGroupRatio(page, size, accountId, state, type);
        return Result.success(pageResult);
    }

    /**
     * 取消未生效的分账比例
     *
     * @param accountId 区域id
     * @param type      分账类型(1-区域分账 2-车辆分账)
     */
    @PutMapping("/editSubAccountRatioState")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_RATIO_DELETE)
    public Result<Void> editSubAccountRatioState(Integer accountId, @RequestParam(defaultValue = "1") Integer type) {
        return subAccountService.editSubAccountRatioState(accountId, type);
    }

    /**
     * 查询用户余额统计
     *
     * @param accountId 品牌id
     * @param phone     用户手机号
     * @return
     */
    @GetMapping("/queryBalance")
    public Result<SubAccountBalanceVO> queryBalance(@NotNull Integer accountId, String phone) {
        return Result.success(subAccountService.queryBalance(accountId, phone));
    }


    /**
     * 分页查询用户余额信息
     *
     * @param page      当前页码
     * @param size      每页显示的行数
     * @param accountId 区域id
     * @param phone     用户手机号
     * @return
     */
    @GetMapping("/queryUserBalancePage")
    public Result<PageResult<SubAccountUserBalanceVO>> queryUserBalancePage(@NotNull Integer page, @NotNull Integer size, @NotNull Integer accountId, String phone) {
        PageResult<SubAccountUserBalanceVO> pageResult = subAccountService.queryUserBalancePage(page, size, accountId, phone);
        return Result.success(pageResult);
    }

    /**
     * 导出用户余额信息
     *
     * @param accountId 区域id
     * @param phone     用户手机号
     * @return
     */
    @GetMapping("/exportUserBalance")
    public Result exportUserBalancePage(@NotNull Integer accountId, String phone) {
        PageResult<SubAccountUserBalanceVO> pageResult = subAccountService.queryUserBalancePage(1, 65535, accountId, phone);
        List<SubAccountUserBalanceVO> list = pageResult.getList();
        list.forEach(SubAccountUserBalanceVO::unitConversion);
        ExcelUtil<SubAccountUserBalanceVO> excel = new ExcelUtil<>(SubAccountUserBalanceVO.class);
        JsonResult UserBalance = excel.exportExcel(list, "用户余额信息");
        return Result.success(UserBalance.getData());
    }


    /**
     * 分页查询用户提现列表
     *
     * @param page      当前页码
     * @param size      每页显示的行数
     * @param accountId 品牌id
     * @return
     */
    @GetMapping("/querySubAccountWithdrawal")
    public Result<PageResult<SubAccountWithdrawalVO>> querySubAccountWithdrawal(@NotNull Integer page, @NotNull Integer size, @NotNull Integer accountId) {
        PageResult<SubAccountWithdrawalVO> pageResult = subAccountService.querySubAccountWithdrawal(page, size, accountId);
        return Result.success(pageResult);
    }

    /**
     * 分账账户提现
     *
     * @param subAccountId 分账账户id
     * @param money        提现金额，单位分
     * @return
     */
    @GetMapping("/withdrawalBalance")
    public Result withdrawalBalance(@NotNull Integer subAccountId, @NotNull Integer money, HttpServletRequest request, String remark) {
        LoginInfo loginInfo = BaseController.getLogin(request);
        return subAccountService.withdrawalBalance(subAccountId, money, loginInfo, remark);
    }

    /**
     * 余额退款
     *
     * @param operaPsw    操作密钥
     * @param userId      用户id
     * @param accountId   品牌id
     * @param refundMoney 退款金额，单位分
     * @return
     */
    @GetMapping("/balanceRefund")
    @OperateLog(module = ModuleEnum.REFUND, methods = MethodEnum.USER_MONEY_REFUND_OPERATION)
    public Result balanceRefund(String operaPsw, Integer userId, Integer accountId, Double refundMoney, HttpServletRequest request) {
        /**操作密码校验*/
        operaPswService.checkOperaPsw(BaseController.getLogin(request), OperaPswEnum.OPERA_PSW_MONEY_CONFIG.getModule(), operaPsw);

        return refundService.userMoneyRefund(BaseController.getLogin(request), new UserMoneyRefundDTO(userId, refundMoney.longValue(), operaPsw));
        //return subAccountService.balanceRefund(userId, accountId, refundMoney);
    }

    /**
     * 手动刷新账户余额
     *
     * @return
     */
    @GetMapping("/refreshBalance")
    public Result refreshBalance() {
        return subAccountService.refreshBalance();
    }

    /**
     * 修改商户账户信息
     *
     * @param subAccountMerchantsDTO
     * @return
     */
    @PutMapping("/updateMerchants")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_EDIT)
    public Result updateMerchants(@RequestBody SubAccountMerchantsDTO subAccountMerchantsDTO) {
        return subAccountService.updateMerchants(subAccountMerchantsDTO);
    }


    /**
     * 修改商户账户信息
     *
     * @param
     * @return
     */
    @PutMapping("/updateBankNumber")
    @OperateLog(module = ModuleEnum.SUBACCOUNT, methods = MethodEnum.SUBACCOUNT_EDIT)
    public Result updateBankNumber(Integer accountId, Integer subAccountId,String bankCardNumber,String openBank) {
        return subAccountService.updateBankCard(accountId,subAccountId,bankCardNumber,openBank);
    }

    /**
     * 调用汇付数据
     * @return Result
     */
    @GetMapping("/getAdaPay")
    public Result getAdaPay() {
        return subAccountService.getAdaPay();
    }
}
